#include <stdlib.h>
#include <iostream>
#include <iomanip>
#include <sys/types.h>
#include <fcntl.h>
#include <time.h>
 
extern "C" {
#include "sis3100_vme_calls.h"
#include "sis3100_dma.h"
}

using namespace std;

int  crate    = -1;
char *dev_fn  = (char *) "/dev/sis1100_00remote";

		

#define SIS3100_VERSION 0x0
/*---------------------------------------------------------------------------*/
void show_SIS3100_status(int handle) 
/*---------------------------------------------------------------------------*/
{
	u_int32_t d;
	int r;

	cerr << "SIS3100 status:";
	if((r=s3100_control_read(handle,SIS3100_VERSION,&d))) {
		cerr  << "show_SIS3100_status():" << endl
		      << "  s3100_control_read() returned " << r << endl;
		cerr.flush();
		exit(1);
	} else {
		cerr << " FW Version: " << ((d & 0xff000000)>>24)
		     << " FW ID: " << ((d & 0x00ff0000)>>16)
		     << " HW Version: " << ((d & 0x0000ff00)>>8)
		     << " Identifier: " << (d & 0x000000ff) << endl;
	}
}
	
		
		
int main(int argc, char **argv)
{
	double rate;
	int c1, c2;
	const int count = 1000000;
	
	if( !(crate = open(dev_fn, O_RDWR, 0)) )	{
		cerr << "ERROR: could not open \"" << dev_fn << "\"" << endl;
		cerr.flush(); 
		exit(1);
	}

	int sisver = sis_driver_version(crate);
	cerr << "SIS driver revision: " << (sisver >> 16) << "." << (sisver & 0xffff) << endl;

	cerr << "vmesysreset...\n" << flush;
	if(int r=vmesysreset(crate)) {
		cerr << "error: vmesysreset() returned " << r << endl << endl;
		cerr.flush();
		exit(1);
	}

	show_SIS3100_status(crate);
	sleep(2);

	c1 = clock();
	for (int i = 0; i < count; i++) {
		u_int32_t val;
		// read status register of SIS3600 card
		int r = vme_A32D32_read(crate, 0x34567000 + 0x000, &val);
		//cerr << hex << val << " ";
	}
	c2 = clock();
	rate =  (double) count / (double)(c2 - c1) * (double)CLOCKS_PER_SEC;
	cerr << "single call: " << rate  << " calls/sec, " 
	     << setprecision(2) << rate*4/1024/1024 << " MByte/s" << endl;
	
	c1 = clock();
	const uint bufsize = 100;
	for (int i = 0; i < count; i+= bufsize) {
		u_int32_t val[bufsize];
		u_int32_t read;
		// read status register of SIS3600 card
		vme_A32DMA_D32FIFO_read(crate, 0x34567000 + 0x000, &val[0], bufsize, &read);
		//cerr << hex << val << " ";
	}
	c2 = clock();
	rate =  (double) count / (double)(c2 - c1) * (double)CLOCKS_PER_SEC;
	cerr << "DMA read: " << rate  << " calls/sec, " 
	     << setprecision(2) << rate*4/1024/1024 << " MByte/s" << endl;
	
	
	close(crate);
}

